from transsys import PromoterElementActivate
from subprocess import Popen, PIPE
import os
import tempfile
from pydot import *
from transsys import *
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure


def whereis(program):
    for path in os.environ.get('PATH', '').split(':'):
        if os.path.exists(os.path.join(path, program)) and \
           not os.path.isdir(os.path.join(path, program)):
            return os.path.join(path, program)
    return None


def tra2svg(tra, svgfile):
    """Generate visualization of the transsys model as svg image.
    Input: transsys code
    ouptput: path to svg file"""
    if (whereis("transdot") != None):
        p0 = Popen(["echo", tra], shell=False, stdout=PIPE)
        p1 = Popen(["transdot"], shell=False, stdout=PIPE, stdin=p0.stdout)
        p2 = Popen(["dot", "-Tsvg", "-o"+svgfile ], shell=False, stdin=p1.stdout, stdout=PIPE)
        err = p2.communicate()[1]
        if err:
            raise StandardError(err)
    else:
        raise StandardError("Missing transdot or dot(graphviz.")

def tra2img(tra, ext):
    """Generate image in given extension from the transsys code. 
    Image extension must be supported by graphviz"""

    if (whereis("transdot") != None):
        p0 = Popen(["echo", tra], shell=False, stdout=PIPE)
        p1 = Popen(["transdot"], shell=False, stdout=PIPE, stdin=p0.stdout)
        p2 = Popen(["dot", "-Kcirco","-T" + ext], shell=False, stdin=p1.stdout, stdout=PIPE, stderr=PIPE)
        
        return p2.communicate()[0]
        #err = p2.communicate()[1]
        #if err:
        #    raise StandardError(err)
    else:
        raise StandardError("Missing transdot or dot(graphviz.")


def dot2img(dot, ext):
    if (whereis("dot") != None):
        p1 = Popen(["echo", dot], shell=False, stdout=PIPE)
        #p2 = Popen(["neato", "-n" , "-T" + ext], shell=False, stdin=p1.stdout, stdout=PIPE, stderr=PIPE)
        p2 = Popen(["dot", "-Kcirco","-T" + ext], shell=False, stdin=p1.stdout, stdout=PIPE, stderr=PIPE)

        return p2.communicate()[0]
        #err = p2.communicate()[1]
        #if err:
        #    raise StandardError(err)
    else:
        raise StandardError("Missing transdot or dot(graphviz.")
def tra2dot(tp, dot_parameters) :
    #TODO: better solution
    tmp = tempfile.mktemp()
    f = open(tmp, "w")
    tp.write_dot(f, dot_parameters)
    import pdb; pdb.set_trace()
    f.close()
    f = open(tmp, "r")
    dot_code = f.read()
    return dot_code

def write_dot(tp):
    graph = Dot(tp.name, graph_type="digraph")
    
    for gene in tp.gene_list:
        node = Node(gene.name)
        node.set("shape", "ellipse")
        #node.set("style", "filled")
        
        product = gene.product.name
        label = "< <TABLE BORDER=\"0\"><TR><TD>"+node.get_name()+"</TD></TR><TR><TD BORDER=\"1\" PORT=\""+product+"\">"+product+"</TD></TR></TABLE> >"
        node.set("label", label)
        for k,v in gene.dot_attributes.items():
            node.set(k,v)
        graph.add_node(node)

        regulated_genes = tp.regulated_genes(product)
        for g in regulated_genes:
            for promoter in g.promoter:
                if isinstance(promoter, PromoterElementActivate):
                    if(product in [i.factor_name() for i in promoter.getIdentifierNodes()]):
                        src = gene.name+":"+product
                        des = g.name
                        edge = Edge(src, des)
                        edge.set("arrowhead", "normal")
                        edge.set("color", "green")
                        graph.add_edge(edge)
                elif isinstance(promoter, PromoterElementRepress):
                    if(product in [i.factor_name() for i in promoter.getIdentifierNodes()]):
                        src = gene.name+":"+product
                        des = g.name
                        edge = Edge(src, des)
                        edge.set("arrowhead", "tee")
                        edge.set("color", "red")
                        graph.add_edge(edge)
    return graph.to_string()
    

def plot(tp, fc_list):
    #construct x_map
    x_map={}
    for index, factor in enumerate(tp.factor_list):
        x_map[factor.name] = index+1
    
    #construct x, y data
    x=[]
    y=[]
    for row in fc_list:
        for index, fc in enumerate(row):
            x.append(index+1)
            y.append(fc)

    fig=Figure()
    graph=fig.add_subplot(111)

    graph.set_xlabel("Factor")
    graph.set_ylabel("Expression level")
    graph.scatter(x,y)
    graph.set_xticks(x)
    graph.set_xticklabels([key for(key, value) in x_map.items()])
    #graph.axis([0,len(x_map.keys())+1, 0,12])
    canvas=FigureCanvas(fig)
    return canvas